package com.chinacoal.microservice.service.impl;

import com.auth0.jwt.JWT;
import com.baomidou.mybatisplus.plugins.Page;
import com.chinacoal.microservice.mapper.*;
import com.chinacoal.microservice.pojo.*;
import com.chinacoal.microservice.service.RoomManagementService;
import com.chinacoal.microservice.util.CodeMsg;
import com.chinacoal.microservice.util.IdcardUtils;
import com.chinacoal.microservice.util.QueryCriteria;
import com.chinacoal.microservice.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author zhuliang
 * @version V1.0
 * @Description: 房源管理-房间管理-实现类
 * @date 2020-11-12 10：56
 */
@Slf4j
@Service
public class RoomManagementServiceImpl implements RoomManagementService {

    @Autowired
    private CcmsSmartleasingRoomMapper roomMapper;

    @Autowired
    private CcmsSmartleasingHouseTypeMapper houseTypeMapper;

    @Autowired
    private CcmsSmartleasingContractMapper contractMapper;

    @Autowired
    private CcmsSmartleasingNoticeMapper noticeMapper;

    @Autowired
    private CcmsSmartleasingExpenseManagMapper expenseManagMapper;

    @Autowired
    private CcmsSmartleasingDeviceManagementMapper deviceManagementMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private  CcmsSmartleasingDeviceChangeMapper deviceChangeMapper;

    @Autowired
    private CcmsSmartleasingExpenseEntryMapper expenseEntryMapper;

    /**
     * @Description: 查询所有的房间信息（带分页）
     * @author zhuliang
     * @date 2020/11/12 10:59
     */
    @Override
    public Result<List<CcmsSmartleasingRoom>> getListByPage(QueryCriteria queryCriteria, String token) {
        //得到登录人信息
        Currency currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getSignature());
        if (null == currency) {
            currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getClaim("phone").asString());
        }

        //设置分页查询条件
        Page<CcmsSmartleasingRoom> toPage = new Page<>(queryCriteria.getPage(), queryCriteria.getPageSize());

        //开始分页查询
        List<CcmsSmartleasingRoom> rooms = roomMapper.getAllByPage(toPage, currency.getProperty(), currency.getManagementOffice());

        return Result.success(rooms, toPage.getTotal());
    }

    /**
     * @Description: 根据房间id查询房间信息
     * @author zhuliang
     * @date 2020/11/12 11:27
     */
    @Override
    public Result<CcmsSmartleasingRoom> getRoomById(String pkRoomId, String token) {
        //得到登录人信息
        Currency currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getSignature());
        if (null == currency) {
            currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getClaim("phone").asString());
        }

        //根据id查询对应的房间信息
        CcmsSmartleasingRoom room = roomMapper.getRoomById(pkRoomId, currency.getProperty(), currency.getManagementOffice());

        //拆分字段，和兼容性处理
        if (null != room) {
            if (StringUtils.isNotEmpty(room.getRoomPicture())) {
                String[] roomPictureSplit = room.getRoomPicture().split(",");
                room.setRoomPictureSplit(roomPictureSplit);
            }
        } else {
            log.error(CodeMsg.NOT_FOUND.toString() + "-->此房间信息无权限访问，或数据丢失-->" + pkRoomId);
            return Result.error(CodeMsg.NOT_FOUND);
        }

        //查询对应的户型信息
        List<CcmsSmartleasingHouseType> houseTypes = houseTypeMapper.getAllByBuildingId(room.getFkBuildingId(), null, null);

        //将多字段的数据，进行拆分返回
        if (null != houseTypes) {
            for (CcmsSmartleasingHouseType houseType : houseTypes) {
                if (StringUtils.isNotEmpty(houseType.getSupportingFacilities())) {
                    String[] splitSupportingFacilities = houseType.getSupportingFacilities().split(",");
                    houseType.setSupportingFacilitiesList(splitSupportingFacilities);
                }
                if (StringUtils.isNotEmpty(houseType.getApartmentRenderings())) {
                    String[] splitApartmentRenderings = houseType.getApartmentRenderings().split(",");
                    houseType.setApartmentRenderingsList(splitApartmentRenderings);
                }
            }
        }

        //写入返回集中
        room.setHouseTypes(houseTypes);

        return Result.success(room);
    }

    /**
     * @Description: 添加房间信息
     * @author zhuliang
     * @date 2020/11/12 11:36
     */
    @Override
    public Result addRoom(String token, CcmsSmartleasingRoom room) {
        //得到登录人id
        Currency currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getSignature());
        if (null == currency) {
            currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getClaim("phone").asString());
        }

        //做编码唯一性验证
        String s = roomMapper.codingUniquenessVerification(room.getUnitCoding(), room.getWaterCostCode(), room.getHotWaterCostCode(),room.getElectricCostCode(), room.getCoalGasCostCode(), null);
        if (StringUtils.isNotBlank(s)) {
            log.error(CodeMsg.NAME_OR_CODE_REPEAT.toString() + "-->编码：" + room.getUnitCoding() +
                    "-->水费编码:" + room.getWaterCostCode()+"-->热水费编码:" + room.getHotWaterCostCode() + "-->电费编码:" + room.getElectricCostCode() + "-->煤气编码:" + room.getCoalGasCostCode());
            return Result.error(CodeMsg.NAME_OR_CODE_REPEAT);
        }

        //同楼宇同楼层房间号唯一性验证
        String verificationByRoomNumber = roomMapper.uniquenessVerificationByRoomNumber(room.getHouseNumber(), room.getFkFloorId(), room.getFkBuildingId(), null);
        if (StringUtils.isNotBlank(verificationByRoomNumber)) {
            log.error(CodeMsg.ROOM_NUMBER_HAS_BEEN_USED.toString() + "-->房间号：" + room.getHouseNumber() +
                    "-->楼宇：" + room.getFkBuildingId() + "-->楼层：" + room.getFkFloorId());
            return Result.error(CodeMsg.ROOM_NUMBER_HAS_BEEN_USED);
        }

        //添加默认的参数
        room.setPkRoomId(UUID.randomUUID() + "");
        room.setCreationDate(new Date());
        room.setLastUpdateDate(new Date());
        room.setCreatedBy(currency.getLoginId());
        room.setLastUpdatedBy(currency.getLoginId());
        room.setFkRoomStatusId("ca68415c-1df1-11eb-9143-00ffb95445a5");
        room.setRentalStatus(0);

        //添加房间信息
        roomMapper.insert(room);

        return Result.success();
    }

    /**
     * @Description: 修改房间信息
     * @author zhuliang
     * @date 2020/11/12 11:42
     */
    @Override
    @Transactional
    public Result updateRoom(String token, CcmsSmartleasingRoom room) {
        //得到登录人id
        Currency currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getSignature());
        if (null == currency) {
            currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getClaim("phone").asString());
        }

        //同楼宇同楼层房间号唯一性验证
        String verificationByRoomNumber = roomMapper.uniquenessVerificationByRoomNumber(room.getHouseNumber(), room.getFkFloorId(), room.getFkBuildingId(), room.getPkRoomId());
        if (StringUtils.isNotBlank(verificationByRoomNumber)) {
            log.error(CodeMsg.ROOM_NUMBER_HAS_BEEN_USED.toString() + "-->房间号：" + room.getHouseNumber() +
                    "-->楼宇：" + room.getFkBuildingId() + "-->楼层：" + room.getFkFloorId());
            return Result.error(CodeMsg.ROOM_NUMBER_HAS_BEEN_USED);
        }

        //做编码唯一性验证
        String s = roomMapper.codingUniquenessVerification(room.getUnitCoding(), room.getWaterCostCode(),room.getHotWaterCostCode(), room.getElectricCostCode(), room.getCoalGasCostCode(), room.getPkRoomId());
        if (StringUtils.isNotBlank(s)) {
            log.error(CodeMsg.NAME_OR_CODE_REPEAT.toString() + "-->编码：" + room.getUnitCoding() + "-->水费编码:" + room.getWaterCostCode() +
                    "-->热水费编码:" + room.getHotWaterCostCode()+"-->电费编码:" + room.getElectricCostCode() + "-->煤气编码:" + room.getCoalGasCostCode());
            return Result.error(CodeMsg.NAME_OR_CODE_REPEAT);
        }

        //修改房间信息中最后修改的时间
        room.setLastUpdateDate(new Date());
        room.setLastUpdatedBy(currency.getLoginId());
        roomMapper.updateById(room);

        //查询对应的通知单信息
        List<CcmsSmartleasingNotice> noticeList = noticeMapper.getNoticeListByRoomId(room.getPkRoomId());
//        CcmsSmartleasingNotice notice = noticeMapper.getNoticeByRoomId(room.getPkRoomId());

        if (noticeList != null) {
            for (CcmsSmartleasingNotice notice : noticeList) {
                //判断是否有生成通知单
                if (notice != null) {
                    //完善通知单消息
                    notice.setLastUpdatedBy(0);
                    notice.setLastUpdateDate(new Date());
                    notice.setAddress(notice.getBuildingName() + "-" + notice.getFloor() + "层-" + notice.getHouseNumber());
                    //notice.setTrashHandlingFee(notice.getUnitPriceGarbageTreatment().multiply(notice.getGarbageTreatmentMagnification()).setScale(2, BigDecimal.ROUND_HALF_UP));
                    if (notice.getUnitPriceElevatorFee() != null) {
                        notice.setElevatorRate(notice.getUnitPriceElevatorFee().multiply(notice.getConstructionArea()).setScale(2, BigDecimal.ROUND_HALF_UP));
                    } else {
                        noticeMapper.updateElevatorFeeToNull(notice.getPkNoticeId());
                    }

                    //修改通知单消息
                    noticeMapper.updateById(notice);

                    //判断是否清除原有数据
                    if (StringUtils.isBlank(notice.getWaterCostCode())) {
                        //清空水费原有数据
                        noticeMapper.clearByWater(notice.getPkNoticeId());
                    }
                    if (StringUtils.isBlank(notice.getElectricCostCode())) {
                        //清空电费原有数据
                        noticeMapper.clearByElectricity(notice.getPkNoticeId());
                    }
                    if (StringUtils.isBlank(notice.getCoalGasCostCode())) {
                        //清除煤气数据
                        noticeMapper.clearByGas(notice.getPkNoticeId());
                    }
                }
            }
        }


        return Result.success();
    }

    /**
     * @Description: 根据房间id批量删除房间信息
     * @author zhuliang
     * @date 2020/11/12 11:47
     */
    @Override
    public Result deleteRoom(String token, String deleteId) {
        //得到登录人id
        Currency currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getSignature());
        if (null == currency) {
            currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getClaim("phone").asString());
        }

        //将要删除的id进行拆分
        String[] ids = deleteId.split(",");

        //判断是否可以删除
        String countByRoomId = contractMapper.getCountByRoomId(ids);
        String s = deviceManagementMapper.deleteRoomByDevice(ids);
        if (StringUtils.isNotBlank(countByRoomId) || StringUtils.isNotBlank(s)) {
            log.error(CodeMsg.DATA_HAS_BEEN_USED.toString() + "-->" + ids);
            return Result.error(CodeMsg.DATA_HAS_BEEN_USED);
        }

        //根据id集合批量删除房间信息
        roomMapper.updateToDeleteById("1",
                new Date(),
                ids,
                currency.getLoginId(),
                currency.getProperty(),
                currency.getManagementOffice());

        return Result.success();
    }

    /**
     * @Description: 条件查询（带分页）
     * @author zhuliang
     * @date 2020/11/12 17:37
     */
    @Override
    public Result<List<CcmsSmartleasingRoom>> queryRoomManagement(QueryCriteria queryCriteria, String token) {
        //得到登录人信息
        Currency currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getSignature());
        if (null == currency) {
            currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getClaim("phone").asString());
        }

        //设置分页查询条件
        Page<CcmsSmartleasingRoom> toPage = new Page<>(queryCriteria.getPage(), queryCriteria.getPageSize());

        //开始分页查询
        List<CcmsSmartleasingRoom> rooms = roomMapper.getAllByCondition(toPage,
                queryCriteria.getFkBuildingId(),
                queryCriteria.getFkRoomTypeId(),
                queryCriteria.getInputString(),
                queryCriteria.getAreaNumberId(),
                queryCriteria.getUnitCoding(),
                queryCriteria.getRoomStatus(),
                currency.getProperty(),
                currency.getManagementOffice());

        return Result.success(rooms, toPage.getTotal());
    }

    /**
     * @Description: 修改出租信息
     * @author zhuliang
     * @date 2020/12/2 15:04
     */
    @Override
    public Result updateByRent(CcmsSmartleasingRoom room, String token) {
        //得到登录人id
        Currency currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getSignature());
        if (null == currency) {
            currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getClaim("phone").asString());
        }

        if (room.getRentalStatus() != 0) {
            //验证电话号码
            if (StringUtils.isNotBlank(room.getContactInformation()) && !IdcardUtils.isPhoneLegal(room.getContactInformation())) {
                log.error(CodeMsg.PHONE_ABNORMAL.toString() + "-->电话号码:" + room.getContactInformation());
                return Result.error(CodeMsg.PHONE_ABNORMAL);
            }
        }

        //修改房间信息中最后修改的时间
        room.setLastUpdateDate(new Date());
        room.setLastUpdatedBy(currency.getLoginId());
        room.setRentalTime(new Date());

        //根据房间id修改房间信息
        roomMapper.updateById(room);

        return Result.success();
    }

    /**
     * @description
     * @author leo
     * @date 2022-12-18 16:07
     */
    @Override
    public Result addDeviceChange(String token, CcmsSmartleasingDeviceChange deviceChange) {
        BigDecimal BD_NEGATIVE_ONE_WITH_2DECIMAL = new BigDecimal("-1.00");

        Currency currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getSignature());
        if (null == currency) {
            currency = (Currency) redisTemplate.opsForValue().get("ccms:" + JWT.decode(token).getClaim("phone").asString());
        }

        BigDecimal bdOldWaterConsumption = null;
        BigDecimal bdOldHotWaterConsumption = null;
        BigDecimal bdOldElectricConsumption = null;
        BigDecimal bdOldGasConsumption = null;


        BigDecimal bdLatestWaterReadingInDCTable;
        BigDecimal bdLatestHotWaterReadingInDCTable;
        BigDecimal bdLatestElectricReadingInDCTable;
        BigDecimal bdLatestGasReadingInDCTable;

        BigDecimal bdOldWaterReading = deviceChange.getOldWaterReading();
        BigDecimal bdOldHotWaterReading = deviceChange.getOldHotWaterReading();
        BigDecimal bdOldElectricReading = deviceChange.getOldElectricReading();
        BigDecimal bdOldGasReading = deviceChange.getOldGasReading();

        String fkRoomYundingId = deviceChange.getFkYundingRoomId();
        Boolean bWaterConsumptionSubtracted = false,bHotWaterConsumptionSubtracted = false,bElectricConsumptionSubtracted = false,bGasConsumptionSubtracted = false;

        //返回本月内换表记录
        List<CcmsSmartleasingDeviceChange> lstDeviceChange = deviceChangeMapper.getAllByCondition(fkRoomYundingId,"true");
        if (lstDeviceChange.size()>0) {
            for (CcmsSmartleasingDeviceChange dc:lstDeviceChange) {
                bdLatestWaterReadingInDCTable =dc.getNewWaterReading();
                bdLatestHotWaterReadingInDCTable =dc.getNewHotWaterReading();
                bdLatestElectricReadingInDCTable =dc.getNewElectricReading();
                bdLatestGasReadingInDCTable =dc.getNewGasReading();

                if (!bWaterConsumptionSubtracted) {
                    if (bdLatestWaterReadingInDCTable != null){
                        if (bdOldWaterReading != null){
                            bdOldWaterConsumption = bdOldWaterReading.subtract(bdLatestWaterReadingInDCTable);
                            bWaterConsumptionSubtracted = true;
                        }
                    }
                }

                if (!bHotWaterConsumptionSubtracted) {
                    if (bdLatestHotWaterReadingInDCTable != null){
                        if (bdOldHotWaterReading != null) {
                            bdOldHotWaterConsumption = bdOldHotWaterReading.subtract(bdLatestHotWaterReadingInDCTable);
                            bHotWaterConsumptionSubtracted = true;
                        }
                    }
                }

                if (!bElectricConsumptionSubtracted) {
                    if (bdLatestElectricReadingInDCTable != null){
                        if (bdOldElectricReading != null) {
                            bdOldElectricConsumption = bdOldElectricReading.subtract(bdLatestElectricReadingInDCTable);
                            bElectricConsumptionSubtracted = true;
                        }
                    }
                }

                if (!bGasConsumptionSubtracted) {
                    if (bdLatestGasReadingInDCTable != null){
                        if (bdOldGasReading != null) {
                            bdOldGasConsumption = bdOldGasReading.subtract(bdLatestGasReadingInDCTable);
                            bGasConsumptionSubtracted = true;
                        }
                    }
                }
            }
        }
        else{
            CcmsSmartleasingExpenseEntry expenseEntry = expenseEntryMapper.getMonthMobilityByRoomId(fkRoomYundingId);
            if (expenseEntry == null)
                return Result.error(CodeMsg.NO_EXPENSE_ENTRY_THIS_MONTH);
            else if (expenseEntry.getPkExpenseEntryId() == null)
                return Result.error(CodeMsg.NO_EXPENSE_ENTRY_THIS_MONTH);

            BigDecimal bdMonthWaterMobility = expenseEntry.getMonthWaterMobility();
            BigDecimal bdMonthHotWaterMobility = expenseEntry.getMonthHotWaterMobility();
            // Attention: the latter is electricity,NOT electric; same for below
            BigDecimal bdMonthElectricMobility = expenseEntry.getMonthElectricityMobility();
            BigDecimal bdMonthGasMobility = expenseEntry.getMonthGasMobility();

            if (expenseEntry.getPkExpenseEntryId() != null) {
                if (bdMonthWaterMobility != null) {
                    if (bdOldWaterReading != null)
                       bdOldWaterConsumption =bdOldWaterReading.subtract(bdMonthWaterMobility);
                }
                if (bdMonthHotWaterMobility != null) {
                    if (bdOldHotWaterReading != null)
                        bdOldHotWaterConsumption =bdOldHotWaterReading.subtract(bdMonthHotWaterMobility);
                }
                if (bdMonthElectricMobility != null) {
                    if (bdOldElectricReading != null)
                        bdOldElectricConsumption =bdOldElectricReading.subtract(bdMonthElectricMobility);
                }
                if (bdMonthGasMobility != null) {
                    if (bdOldGasReading != null)
                        bdOldGasConsumption =bdOldGasReading.subtract(bdMonthGasMobility);
                }

            }
        }

        deviceChange.setPkDeviceChangeId(UUID.randomUUID().toString());
        deviceChange.setCreatedBy(currency.getLoginId());
        deviceChange.setCreationDate(new Date());
        deviceChange.setFkYundingRoomId(fkRoomYundingId);
        deviceChange.setOldWaterConsumption(bdOldWaterConsumption);
        deviceChange.setOldHotWaterConsumption(bdOldHotWaterConsumption);
        deviceChange.setOldElectricConsumption(bdOldElectricConsumption);
        deviceChange.setOldGasConsumption(bdOldGasConsumption);

        deviceChangeMapper.insert(deviceChange);
        return  Result.success();
    }

    /**
     * @description
     * @author leo
     * @date 2022-12-19 18:13
     */
    @Override
    public Result<List<CcmsSmartleasingDeviceChange>> getDeviceChangesByRoomId_CurrentMonth(String pkRoomId, String bCurrentMonth, String token) {
        List<CcmsSmartleasingDeviceChange> lstDeviceChange = deviceChangeMapper.getAllByCondition(pkRoomId,bCurrentMonth);
        return Result.success(lstDeviceChange);
    }
}
